/*
 *  SPAGL Copyright (C) 2008 Sam Pottinger
 *  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 
 *  General Public License as published by the Free Software Foundation; either version 2.1 of the License, or 
 *  (at your option) any later version. This library is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 *  See the GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License along with this library; if not, 
 *  write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */

package spagswing;

import java.awt.Component;
import net.miginfocom.swing.*;
import javax.swing.JDialog;
import spagcore.*;

/**
 * A JDialog (javax.swing.JDialog) that conforms to the SpaglCoreWindow interface
 * @author Sam Pottinger
 */
public class SpaglWindow extends JDialog implements SpaglCoreWindow {

	// Searialize
	private static final long serialVersionUID = 1L;
	
	// Wrap around the JDialog close constants
	public static final int DO_NOTHING_ON_CLOSE = JDialog.DO_NOTHING_ON_CLOSE;
	public static final int HIDE_ON_CLOSE = JDialog.HIDE_ON_CLOSE;
	public static final int DISPOSE_ON_CLOSE = JDialog.DISPOSE_ON_CLOSE;
	public static final int EXIT_ON_CLOSE = JDialog.EXIT_ON_CLOSE;
	
	private SpaglCoreApp parentApp;
	private MigLayout layoutManager;
	
	/**
	 * The bare-bones constructor for a window
	 * @param newApp The application that this window will belong to
	 * @param title The title to be displayed at the top of this window
	 * @param newLayoutManager The layout manager to be used in this window
	 */
	public SpaglWindow(SpaglCoreApp newApp, String title, MigLayout newLayoutManager)
	{
		super();
		super.setTitle(title);
		layoutManager = newLayoutManager;
		parentApp = newApp;
		super.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.getContentPane().setLayout(layoutManager);
		parentApp.addWindow(this);
		
	}
	
	/**
	 * Creates a new window with a default layout manager (MigLayout)
	 * @param newApp The application that this window will belong to
	 * @param title The title to be displayed at the top of this window
	 */
	public SpaglWindow(SpaglCoreApp newApp, String title)
	{
		super();
		super.setTitle(title);
		layoutManager = new MigLayout("fillx", "[left]rel[grow,fill]", "[]10[]");
		parentApp = newApp;
		super.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.getContentPane().setLayout(layoutManager);
		parentApp.addWindow(this);
	}
	
	/**
	 * Creates a new window as a child of another window
	 * @param newApp The application that this window will belong to
	 * @param title The title to be displayed at the top of this window
	 * @param newLayoutManager The layout manager to be used in this window
	 * @param parent The window that this will be a child of
	 */
	public SpaglWindow(SpaglCoreApp newApp, String title, MigLayout newLayoutManager, SpaglCoreWindow parent)
	{
		super((SpaglWindow)parent);
		super.setTitle(title);
		layoutManager = newLayoutManager;
		parentApp = newApp;
		super.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.getContentPane().setLayout(layoutManager);
		parentApp.addWindow(this);
	}
	
	/**
	 * Creates a new window as a child of another window with the default layout manager (MigLayout)
	 * @param newApp The application that this window will belong to
	 * @param title The title to be displayed at the top of this window
	 * @param parent The window that this will be a child of
	 */
	public SpaglWindow(SpaglCoreApp newApp, String title, SpaglCoreWindow parent)
	{
		super((SpaglWindow)parent);
		super.setTitle(title);
		layoutManager = new MigLayout("fillx", "[left]rel[grow,fill]", "[]10[]");
		parentApp = newApp;
		super.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.getContentPane().setLayout(layoutManager);
		parentApp.addWindow(this);
	}

	@SuppressWarnings("deprecation")
	/**
	 * Preform the close event/code
	 */
	public void close() {
		
		int co = super.getDefaultCloseOperation();
		switch(co) {
			case DO_NOTHING_ON_CLOSE: return;
			case HIDE_ON_CLOSE: super.hide(); break;
			case DISPOSE_ON_CLOSE: super.dispose(); break;
			case EXIT_ON_CLOSE: System.exit(0); break;
			default: throw new IllegalArgumentException("Event not supported by this widget");
		}
		
	}

	/**
	 * Gets the actions that will be taken when this window is closed
	 * @return The integer representation of the close operation
	 */
	public int getCloseOperation() {
		return super.getDefaultCloseOperation();
	}

	/**
	 * Determines how the window will close
	 * @param newOperation The string representation of the desired close operation
	 */
	public void setCloseOperation(String newOperation) {
		if(newOperation.equals(NOTHING)) super.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		else if (newOperation.equals(HIDE)) super.setDefaultCloseOperation(HIDE_ON_CLOSE);
		else if (newOperation.equals(DISPOSE)) super.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		else if (newOperation.equals(EXIT)) super.setDefaultCloseOperation(EXIT_ON_CLOSE);
		else throw new java.lang.IllegalArgumentException();
	}
	
	/**
	 * Determines how the window will close
	 * @param newOperation The integer representation of the desired close operation
	 */
	public void setCloseOperation(int newOperation)
	{
		super.setDefaultCloseOperation(newOperation);
	}

	/**
	 * Prepares the window and shows it to the user
	 */
	public void display() {
		super.pack();
		super.setVisible(true);
	}
	
	/**
	 * Gets the layout manager attached to this window
	 * @return The library-specific MigLayout manager attached to this object
	 */
	public MigLayout getLayoutManager()
	{
		return layoutManager;
	}
	
	/**
	 * Sets the MigLayout manager to be used by this object
	 * @param newLayoutManager The MigLayout manager that will be attached to this window
	 */
	public void setLayoutManager(MigLayout newLayoutManager)
	{
		this.getContentPane().setLayout(newLayoutManager);
		layoutManager = newLayoutManager;
	}

	/**
	 * Places a widget on this container with the given string parameters
	 * @param newWidget the target widget to be placed in this container
	 * @param parameters the string parameters for the layout manager
	 */
	public void placeWidget(SpaglCoreWidget newWidget, String parameters) {
		
		this.placeWidget((Component)newWidget, parameters);
		
	}
	
	/**
	 * Places a widget on this container with the given string parameters
	 * @param newWidget the target widget to be placed in this container
	 * @param parameters the string parameters for the layout manager
	 */
	public void placeWidget(Component newWidget, String parameters)
	{
		this.getContentPane().add(newWidget, parameters);
	}
	
	/**
	 * Gets the parent SpaglApp that this window belongs to
	 * @return The SpaglApp that this window belongs to as a SpaglCoreApp
	 */
	public SpaglCoreApp getApp()
	{
		return parentApp;
	}

	/**
	 * Binds an event to to a method so that when the event is fired the method is called
	 * @param eventID the integer (int) id of the event to be bound <br>(string constant ACTIVATED_EVENT, WINDOW_CLOSING_EVENT, DEACTIVATED_EVENT, WINDOW_RESTORED_EVENT, or WINDOW_MINIMIZED_EVENT)
	 * @param method The name of the method to be called when the event is fired
	 * @param o The object where the method is to be invoked
	 */
	public void addEventListener(int eventID, String method, Object o) {
		try{
			switch(eventID)
			{
				case SpaglCoreEvent.ACTIVATED_EVENT: this.addWindowListener(new SpaglEventListener(o.getClass().getMethod(method, SpaglCoreEvent.class), o, SpaglEvent.ACTIVATED_EVENT));
				case SpaglCoreEvent.WINDOW_CLOSING_EVENT: this.addWindowListener(new SpaglEventListener(o.getClass().getMethod(method, SpaglCoreEvent.class), o, SpaglEvent.WINDOW_CLOSING_EVENT));
				case SpaglCoreEvent.DEACTIVATED_EVENT: this.addWindowListener(new SpaglEventListener(o.getClass().getMethod(method, SpaglCoreEvent.class), o, SpaglEvent.DEACTIVATED_EVENT));
				case SpaglCoreEvent.WINDOW_RESTORED_EVENT: this.addWindowListener(new SpaglEventListener(o.getClass().getMethod(method, SpaglCoreEvent.class), o, SpaglEvent.WINDOW_RESTORED_EVENT));
				case SpaglCoreEvent.WINDOW_MINIMIZED_EVENT: this.addWindowListener(new SpaglEventListener(o.getClass().getMethod(method, SpaglCoreEvent.class), o, SpaglEvent.WINDOW_MINIMIZED_EVENT));
				default: throw new IllegalArgumentException("Event not supported by this widget");
			}}
		catch (SecurityException e) {e.printStackTrace();} 
		catch (NoSuchMethodException e) {e.printStackTrace();}
		
	}

}
